package com.boc.ewr.uniapp.api.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.boc.ewr.bcimp.entity.BusAcctInfo;
import com.boc.ewr.bcimp.entity.CaBalDtl;
import com.boc.ewr.bcimp.entity.CaRtnList;
import com.boc.ewr.bcimp.entity.Pro;
import com.boc.ewr.bcimp.service.ICaBalDtlService;
import com.boc.ewr.bcimp.service.ICaRtnListService;
import com.boc.ewr.bcimp.service.IProService;
import com.boc.ewr.business.entity.AcctUncaDtl;
import com.boc.ewr.risk.service.IProRiskService;
import com.boc.ewr.uniapp.api.service.INotificatDataService;
import com.boc.ewr.uniapp.api.vo.CaRateVo;
import com.boc.ewr.util.file.enumeration.*;
import org.checkerframework.checker.units.qual.A;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.SysDepartModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

/**
 * @author : Wzz
 * @create : 2023-06- 09- 10:51
 * @desc :
 */
@Service
public class NotificatDataServiceImpl implements INotificatDataService {

    @Autowired
    private ISysBaseAPI sysBaseAPI;

    @Autowired
    private IProService proService;

    @Autowired
    private ICaBalDtlService caBalDtlService;

    @Autowired
    private ICaRtnListService caRtnListService;

    /*非重点的不剔除、重点的剔除，已回执不剔除，未回执的剔除--可剔除考核*/
    @Override
    public List<CaRateVo> getProSignStatus(List<String> orgCodeList) {
        List<CaRateVo> resultList = new ArrayList<>();
        for (String orgCode : orgCodeList) {
            CaRateVo caRateVo = new CaRateVo();

            SysDepartModel sysDepartModel = sysBaseAPI.selectAllById(orgCode);
            caRateVo.setOrgNm(sysDepartModel.getDepartName());
            caRateVo.setOrgNo(orgCode);
            caRateVo.setRateName("对账协议签约情况");
            caRateVo.setRateData(this.genProSignStatus(orgCode));
            resultList.add(caRateVo);
        }
        return resultList;
    }

    // 对账协议签约情况				Pro未签约/总数
    private String genProSignStatus(String orgCode) {
        long countAllAcct = proService.count(new LambdaQueryWrapper<Pro>().eq(Pro::getSignedOrg, orgCode));
        // 若当前网点下没有客户，则直接返回暂无数据
        if (countAllAcct == 0L) {
            return "暂无数据";
        }
        // 获取当前网点下未签约的账户总数
        long countUnSignAcct = proService.count(new LambdaQueryWrapper<Pro>().eq(Pro::getSignedOrg, orgCode).eq(Pro::getSingedType, SignTypeEnum.UNSIGNED.getIndex()));
        BigDecimal result = new BigDecimal(1)
                .subtract(BigDecimal.valueOf(countUnSignAcct).divide(BigDecimal.valueOf(countAllAcct), 4, BigDecimal.ROUND_HALF_UP))
                .multiply(BigDecimal.valueOf(100))
                .setScale(2, RoundingMode.HALF_UP);
        return result + "%";
    }

    @Override
    public List<CaRateVo> getCaRtnRate(List<String> orgCodeList) {
        List<CaRateVo> resultList = new ArrayList<>();
        for (String orgCode : orgCodeList) {
            CaRateVo caRateVo = new CaRateVo();

            SysDepartModel sysDepartModel = sysBaseAPI.selectAllById(orgCode);
            caRateVo.setOrgNm(sysDepartModel.getDepartName());
            caRateVo.setOrgNo(orgCode);
            caRateVo.setRateName("对账回执率");
            caRateVo.setRateData(this.genCaRtnRate(orgCode));
            resultList.add(caRateVo);
        }
        return resultList;
    }

    // 对账回执率				回执查询清单中（有效回执）/余额对账单明细
    private String genCaRtnRate(String orgCode) {
        long countAllAcct = caBalDtlService.count(
                new LambdaQueryWrapper<CaBalDtl>()
                        .eq(CaBalDtl::getObranchNo, orgCode)
        );
        // 若当前网点下没有客户，则直接返回暂无数据
        if (countAllAcct == 0L) {
            return "暂无数据";
        }
        // 获取当前网点下回执查询清单中的有效回执总数
        // 有效对账状态List
        Set<String> validIndexSet = ReturnStatusEnum.getValidIndexSet();
        /*List<String> validCaStatusList = new ArrayList<>();
        validCaStatusList.add(ReturnStatusEnum.STATUS14.getIndex());
        validCaStatusList.add(ReturnStatusEnum.STATUS15.getIndex());
        validCaStatusList.add(ReturnStatusEnum.STATUS20.getIndex());
        validCaStatusList.add(ReturnStatusEnum.STATUS25.getIndex());
        validCaStatusList.add(ReturnStatusEnum.STATUS13.getIndex());*/
        long countRtnAcct = caRtnListService.count(
                new LambdaQueryWrapper<CaRtnList>()
                        .eq(CaRtnList::getOrgBranchNo, orgCode)
                        .in(CaRtnList::getRtnSta, validIndexSet)
        );
        BigDecimal result = new BigDecimal(1)
                .subtract(BigDecimal.valueOf(countRtnAcct).divide(BigDecimal.valueOf(countAllAcct), 4, BigDecimal.ROUND_HALF_UP))
                .multiply(BigDecimal.valueOf(100))
                .setScale(2, RoundingMode.HALF_UP);
        return result + "%";
    }

    @Override
    public Map<String, List<CaRateVo>> getEBankSignRate(List<String> orgCodeList) {
        // 单一网银签约率List
        List<CaRateVo> eBankSignRateList = new ArrayList<>();
        // 新开账户签约网银渠道List
        List<CaRateVo> newAcctSignRateList = new ArrayList<>();
        for (String orgCode : orgCodeList) {
            CaRateVo caRateVo = new CaRateVo();

            SysDepartModel sysDepartModel = sysBaseAPI.selectAllById(orgCode);
            caRateVo.setOrgNm(sysDepartModel.getDepartName());
            caRateVo.setOrgNo(orgCode);
            caRateVo.setRateName("单一网银签约率");
            caRateVo.setRateData(this.genEBankSignRate(orgCode));
            eBankSignRateList.add(caRateVo);

            caRateVo.setRateName("新开账户签约网银渠道");
            caRateVo.setRateData(this.genNewAcctSignRate(orgCode));
            newAcctSignRateList.add(caRateVo);
        }
        Map<String, List<CaRateVo>> resultMap = new HashMap();
        resultMap.put("单一网银签约率", eBankSignRateList);
        resultMap.put("新开账户签约网银渠道", newAcctSignRateList);
        return resultMap;
    }

    // 单一网银签约率			网银签约率=网银渠道协议数/协议总数*100%	Pro
    private String genEBankSignRate(String orgCode) {
        long countAllAcct = proService.count(new LambdaQueryWrapper<Pro>().eq(Pro::getSignedOrg, orgCode));
        // 若当前网点下没有客户，则直接返回暂无数据
        if (countAllAcct == 0L) {
            return "暂无数据";
        }
        // 获取当前网点下网银渠道协议总数
        long countEBankAcct = proService.count(
                new LambdaQueryWrapper<Pro>()
                        .eq(Pro::getSignedOrg, orgCode)
                        .eq(Pro::getSendChannel, ProSendChannelEnum.EBANK.getIndex())
        );
        BigDecimal result = new BigDecimal(1)
                .subtract(BigDecimal.valueOf(countEBankAcct).divide(BigDecimal.valueOf(countAllAcct), 4, BigDecimal.ROUND_HALF_UP))
                .multiply(BigDecimal.valueOf(100))
                .setScale(2, RoundingMode.HALF_UP);
        return result + "%";
    }

    // 新开账户签约网银渠道		网银签约率=网银渠道协议数/协议总数*100%	Pro
    private String genNewAcctSignRate(String orgCode) {
        // 计算143天前的时间(开户至今小于143天,为新开账户)
        LocalDateTime localDateTime = LocalDateTime.now().minusDays(143);
        Date from = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());

        long countAllAcct = proService.count(
                new LambdaQueryWrapper<Pro>()
                        .eq(Pro::getSignedOrg, orgCode)
                        .between(Pro::getSingedDate, from, new Date())
        );
        // 若当前网点下没有客户，则直接返回暂无数据
        if (countAllAcct == 0L) {
            return "暂无数据";
        }
        // 获取当前网点下新开账户网银渠道协议总数
        long countEBankAcct = proService.count(
                new LambdaQueryWrapper<Pro>()
                        .eq(Pro::getSignedOrg, orgCode)
                        .eq(Pro::getSendChannel, ProSendChannelEnum.EBANK.getIndex())
                        .between(Pro::getSingedDate, from, new Date())
        );
        BigDecimal result = new BigDecimal(1)
                .subtract(BigDecimal.valueOf(countEBankAcct).divide(BigDecimal.valueOf(countAllAcct), 4, BigDecimal.ROUND_HALF_UP))
                .multiply(BigDecimal.valueOf(100))
                .setScale(2, RoundingMode.HALF_UP);
        return result + "%";
    }

    @Override
    public List<CaRateVo> getEBankRtnRate(List<String> orgCodeList) {
        List<CaRateVo> resultList = new ArrayList<>();
        for (String orgCode : orgCodeList) {
            CaRateVo caRateVo = new CaRateVo();

            SysDepartModel sysDepartModel = sysBaseAPI.selectAllById(orgCode);
            caRateVo.setOrgNm(sysDepartModel.getDepartName());
            caRateVo.setOrgNo(orgCode);
            caRateVo.setRateName("网银对账回执率");
            caRateVo.setRateData(this.genEBankRtnRate(orgCode));
            resultList.add(caRateVo);
        }
        return resultList;
    }

    // 网银对账回执率				回执查询清单中（有效回执）/余额对账单明细
    private String genEBankRtnRate(String orgCode) {
        long countAllAcct = caBalDtlService.count(
                new LambdaQueryWrapper<CaBalDtl>()
                        .eq(CaBalDtl::getObranchNo, orgCode)
                        .eq(CaBalDtl::getRtnChannel, ReturnChannelEnum.ONLINE.getIndex())
        );
        // 若当前网点下没有客户，则直接返回暂无数据
        if (countAllAcct == 0L) {
            return "暂无数据";
        }
        // 获取当前网点下回执查询清单中的有效回执总数
        // 有效对账状态List
        Set<String> validIndexSet = ReturnStatusEnum.getValidIndexSet();
        /*List<String> validCaStatusList = new ArrayList<>();
        validCaStatusList.add(ReturnStatusEnum.STATUS14.getIndex());
        validCaStatusList.add(ReturnStatusEnum.STATUS15.getIndex());
        validCaStatusList.add(ReturnStatusEnum.STATUS20.getIndex());
        validCaStatusList.add(ReturnStatusEnum.STATUS25.getIndex());
        validCaStatusList.add(ReturnStatusEnum.STATUS13.getIndex());*/
        long countRtnAcct = caRtnListService.count(
                new LambdaQueryWrapper<CaRtnList>()
                        .eq(CaRtnList::getOrgBranchNo, orgCode)
                        .eq(CaRtnList::getRtnChannel, ReturnChannelEnum.ONLINE.getIndex())
                        .in(CaRtnList::getRtnSta, validIndexSet)

        );
        BigDecimal result = new BigDecimal(1)
                .subtract(BigDecimal.valueOf(countRtnAcct).divide(BigDecimal.valueOf(countAllAcct), 4, BigDecimal.ROUND_HALF_UP))
                .multiply(BigDecimal.valueOf(100))
                .setScale(2, RoundingMode.HALF_UP);
        return result + "%";
    }
}
